package com.wiscamp.ninechapters.panels.application.services;

import com.wiscamp.ninechapters.panels.application.assemblers.ParameterAssembler;
import com.wiscamp.ninechapters.panels.application.command.CreateParameterCommand;
import com.wiscamp.ninechapters.panels.application.command.UpdateParameterCommand;
import com.wiscamp.ninechapters.panels.application.vo.ParameterVO;
import com.wiscamp.ninechapters.panels.domain.repositories.ParameterRepository;
import com.wiscamp.ninechapters.panels.domain.services.ParameterService;
import cube.ddd.application.BaseAppService;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.application.command.DisableCommand;
import cube.ddd.application.command.EnableCommand;
import cube.ddd.aspect.HandleServiceException;
import cube.ddd.common.query.PagedObjects;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.AppServiceUtils;
import jakarta.validation.Valid;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public class ParameterAppService extends BaseAppService {

    private final ParameterRepository parameterRepository;

    private final ParameterService parameterService;

    public ParameterAppService(ParameterRepository parameterRepository, ParameterService parameterService) {
        this.parameterRepository = parameterRepository;
        this.parameterService = parameterService;
    }

    @HandleServiceException
    public ParameterVO getParameter(long parameterId) {
        return AppServiceUtils.getById(parameterId, parameterService::getParameter,
                ParameterAssembler.Instance::toParameterVO);
    }

    @HandleServiceException
    public ParameterVO getParameterByCode(long appId, String parameterCode) {
        return AppServiceUtils.getByIdAndText(appId, parameterCode, parameterRepository::getParameterByCode,
                ParameterAssembler.Instance::toParameterVO);
    }

    @HandleServiceException
    public Collection<ParameterVO> getParametersByName(long appId, String parameterName) {
        return AppServiceUtils.getListByIdAndText(appId, parameterName, parameterRepository::getParametersByName,
                ParameterAssembler.Instance::toParameterVO);
    }

    @HandleServiceException
    public Collection<ParameterVO> getParametersByGroup(long appId, String appGroup) {
        return AppServiceUtils.getListByIdAndText(appId, appGroup, parameterRepository::getParametersByGroup,
                ParameterAssembler.Instance::toParameterVO);
    }

    @HandleServiceException
    public PagedObjects<ParameterVO> getParametersByQuery(PagedQuery pagedQuery) {
        var pagedObjects = parameterRepository.getParametersByQuery(pagedQuery);
        return AppServiceUtils.convertPagedObjects(pagedObjects, ParameterAssembler.Instance::toParameterVO);
    }

    @HandleServiceException
    public ParameterVO createParameter(@Valid CreateParameterCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), parameterService::createParameter,
                ParameterAssembler.Instance::toParameterVO, ParameterAssembler.Instance::fromCreateCommand);
    }

    @HandleServiceException
    public ParameterVO updateParameter(@Valid UpdateParameterCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), parameterService::updateParameter,
                ParameterAssembler.Instance::toParameterVO, ParameterAssembler.Instance::fromUpdateCommand);
    }

    @HandleServiceException
    public boolean deleteParameter(@Valid DeleteCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.delete(command.getId(), command.getOperatorId(), parameterService::deleteParameter);
    }

    @HandleServiceException
    public boolean enableParameter(@Valid EnableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.enable(command.getId(), command.getOperatorId(), parameterService::enableParameter);
    }

    @HandleServiceException
    public boolean disableParameter(@Valid DisableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.disable(command.getId(), command.getOperatorId(), parameterService::disableParameter);
    }
}
